Retour d'expérience sur Haskell

Avec maintenant 5 ans d'expériences sur Haskell, il est maintenant venu pour moi de rendre un verdict sur ce langage et certains de ses aspects.

Typage

La première chose qui est frappante avec Haskell, c'est la force du typage !

Pour avoir utilisé des langages de programmation ou une variable peut posséder différents types suivant le contexte, il est appréciable de pouvoir compter sur un langage possédant des gardes fous de ce côté.

Un autre point appréciable avec Haskell, est la possibilité de pouvoir utiliser des types standards pour gérer des fonctions devant retourner plusieurs types de valeurs.

Créer des types combinés et/ou récursif avec Haskell est un vrai plaisir et sécuriser son code en créant des types "détrompeur" est extrêmement simple.

Inférence de types

Le compilateur de Haskell offre un mécanisme très puissant qui lui permet de calculer les types des fonctions définies par l'utilisateur. Ceci permet de trouver immédiatement les erreurs de type au sein d'une fonction ou entre les fonctions et d'apporter des solutions. Cette fonctionnalité est d'autant plus intéressante qu'elle permet de calculer les types les plus généraux possibles.

L'inférence de type est donc un allié précieux pour fiabiliser le code et trouver les incohérences entre une fonction est sa documentation associée.

Structuration du code

Un autre point positif d'Haskell, c'est la lisibilité du code et la façon dont il est structuré.

Lorsqu'un langage de programmation (comme le C) est très voire trop permissif sur la syntaxe et la structuration du code on peut arriver rapidement à quelque chose d'illisible et de très dur à reprendre par la suite.

Haskell fonctionne comme Python et c'est l'indentation des lignes qui définit les blocs de code ce qui le rend plus lisible que certains autres langages.

Classes et polymorphisme

Haskell permet d'organiser son code en utilisant des classes comme en C++ et en Python. La différence avec ces langages est que avec Haskell on n'a pas des classes d'objets mais des classes de fonctions.

Un des intérêts des classes est de pouvoir utiliser le polymorphisme, c’est-à-dire la capacité de pouvoir utiliser une fonction avec plusieurs types de données.

Je trouve personnellement Haskell plus efficace, intuitif et meilleur sur ce point que C++, même s’il existe quelques différences.

Il est possible avec Haskell de faire varier le type de sortie d'une fonction, ce qui n'est pas possible en C++ (Enfin, pas à ma connaissance).

Une autre différence avec C++ est qu'une fonction polymorphe possédant le même nom ne peut pas avoir un nombre d'arguments différents (alors que cela est possible en C++). Et personnellement, je trouve cela plus logique (mathématiquement parlant).

Il n'est également pas possible, lorsque l'on dérive une classe avec Haskell, de restreindre l'accès à certaines fonctions comme en C++ avec les mots clefs : public, private, protected. Ces restrictions peuvent avoir de l'intérêt mais pour mon usage, cela n'a pas d'importance.

Agilité

Le typage fort allié à l'inférence de types permettent de détecter dès la compilation toutes les erreurs de types et les paramètres manquants.

Lorsque l'on veut modifier en profondeurs et rapidement les fonctions d'un programme, cela apporte un avantage considérable. Cela permet d'éviter une longue phase de test, de gagner en temps et en fiabilité et de mettre le programme en exploitation plus rapidement.

Il est donc plus facile de faire évoluer des programmes écrits avec Haskell que ceux écrits dans un autre langage (et plus particulièrement Python).

Fiabilité

Ce que j'apprécie également avec Haskell, c'est sa robustesse et sa fiabilité. Avec Haskell, quand la compilation marche… tout marche ! … ou presque !

Le compilateur GHC repère la grande majorité des erreurs de programmation à la compilation et permet de réduire considérablement le risque d'erreurs. Néanmoins, certaines erreurs ne sont pas détectables à la compilation.

Et évidemment, lorsque l'on débute, on n'échappe pas à quelques pièges comme:

Mais on apprend vite à se prémunir contre ces erreurs.

Il existe également d'autres pièges qui apparaissent lors d'une utilisation plus poussée ou lorsque l'on travaille avec les monades. Mais un programmeur qui arrive a ce niveau a généralement toutes les compétences pour diagnostiquer ces problèmes et les résoudre.

Performances

Une légende court dans le monde de l'informatique: « Les langages de programmation fonctionnels sont lents ». Cette assertion était sûrement valable à une époque, au début de l'informatique, dans les années 70/80. Mais maintenant, ce n'est plus le cas.

Certes, Haskell est plus lent que le langage C/C++ ou que le Fortran, mais il est bien plus rapide que des langages comme Python ou PHP. Ses performances sont dans l'ensemble comparables à celles de Java ou encore C# et sur certains benchmarks, il est même plus rapide.

Pour se rendre compte des performances comparées de Haskell avec d'autres langages, faites un tour sur le site The Computer Language Benchmarks Game1.

Comme on peut le voir les performances de Haskell sont généralement 2 à 5 fois plus lentes comparées à du C++, contre 3 à 7 pour Java, C#, OCAML et contre 15, 30, 50 voir même 100 fois plus lentes pour Python, Ruby, PHP, Julia, Go.

Bref, les performances de Haskell sont tout à fait honorables et les rumeurs concernant sa prétendue lenteur sont infondées.

Documentation

Un autre point fort de Haskell, c'est la qualité de la documentation qu'il est possible de générer avec haddock le générateur de documentation spécifique de Haskell. Il permet de créer une documentation claire, lisible, efficace et détaillée. Il est possible de générer toutes les mises en forme traditionnelles (Gras, Italiques, codes…) mais également d'inclure des exemples de code, des images, des liens vers d'autres morceaux de la documentation…

Bref, si écrire sa documentation est toujours une étape laborieuse dans le développement d'un programme informatique, avec Haddock, on aura au final la satisfaction d'avoir une documentation de très bonne qualité.

Enfin, il est à noter qu'avec le mécanisme d'inférence de type propre à Haskell, la documentation sera toujours en cohérence avec le code associé. En effet, il est tout simplement impossible de générer une documentation non conforme avec les fichiers sources. Encore une façon d'avoir toujours un code de qualité.

A titre d'exemple, la documentation d'une bibliothèque que j'ai écrite avec Haskell: HsMesher

Difficultés

Une autre légende court sur les langages fonctionnels: « Les langages de programmation fonctionnels sont réservés à l'élite des programmeurs et à la recherche en intelligence artificielle »

Il est vrai que passer d'un langage impératif à un langage fonctionnel n'est pas si simple. Il y a un véritable saut à faire afin de se plonger dans une logique et un concept très différents de ceux qu'on a connu auparavant.

Il est également vrai que certaines choses qui sont simples et intuitives avec des langages impératifs (accès aux fichiers, gestions des exceptions, interactions…) le sont moins avec Haskell de par son mode de fonctionnement.

Pourtant la façon d'organiser le code, la sûreté du typage, la programmation par empreintes , la pureté du langage… permettent de résoudre des problèmes souvent plus simplement qu'avec d'autres langages.

On pourrait même dire que :

Haskell simplifie ce qui est complexe autant qu'il complique ce qui est simple !

Ce qui peut apparaître déroutant lors d'une première utilisation.

Néanmoins, ce saut n'est pas insurmontable et une personne motivée qui s'en donne les moyens est tout à fait capable d'apprendre Haskell rapidement, ce qui s'avérera très rentable sur le long terme.

Avis général

Dans l'ensemble, mon retour d'expérience sur Haskell est excellent et Haskell est devenu mon langage principal de développement.

Utiliser un langage fonctionnel comme Haskell pour développer rapidement des programmes "maisons" comporte un intérêt certain et s'avère plus "rentable" en termes de développement et de mise au point que d'autres langages.

Comparer Haskell avec d'autres langages fonctionnels n'est malheureusement pas possible pour moi a ce stade. Bien que j'aie déjà fait quelques lignes de code avec OCAML, je n'ai pas l'expérience nécessaire sur ce langage pour rendre un verdict. Quant à ERLANG, ma connaissance de ce langage n'a pas dépassé le stade du tutoriel.


Notes

1.

Voici certains des résultats de ces tests.